package com.bizmda.bizsip.sink.processor;

import cn.hutool.json.JSONObject;
import com.bizmda.bizsip.common.*;
import com.bizmda.bizsip.config.AbstractSinkConfig;
import com.bizmda.bizsip.sink.api.SinkCircuitBreaker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * @author shizhengye
 */
@Slf4j
public class SinkRestController {
    private final AbstractSinkConfig sinkConfig;
    private final AbstractSinkProcessor sinkProcessor;
    private final SinkCircuitBreaker sinkCircuitBreaker;

    public SinkRestController(AbstractSinkConfig sinkConfig) throws BizException {
        this.sinkConfig = sinkConfig;
        this.sinkCircuitBreaker = new SinkCircuitBreaker(sinkConfig);
        switch (sinkConfig.getProcessor()) {
            case AbstractSinkConfig.PROCESSOR_DEFAULT:
                this.sinkProcessor = new SinkProcessor(sinkConfig);
                break;
            case AbstractSinkConfig.PROCESSOR_BEAN:
                this.sinkProcessor = new BeanSinkProcessor(sinkConfig);
                break;
            case AbstractSinkConfig.PROCESSOR_SINK_BEAN:
                this.sinkProcessor = new SinkBeanSinkProcessor(sinkConfig);
                break;
            default:
                throw new BizException(BizResultEnum.SINK_TYPE_IS_ERROR);
        }
    }

    @ResponseBody
    public BizMessage<JSONObject> service(@RequestBody BizMessage<JSONObject> inMessage) {
        JSONObject outJsonObject;
        log.trace("Sink同步服务收到消息:\n{}", BizUtils.buildBizMessageLog(inMessage));
        if (this.sinkConfig == null || this.sinkConfig.getId() == null) {
            return BizMessage.buildFailMessage(inMessage, new BizException(BizResultEnum.SINK_SINKID_IS_NULL));
        }
        try {
            BizTools.bizMessageThreadLocal.set(inMessage);
            SinkCircuitBreaker.sinkCircuitBreakerThreadLocal.set(this.sinkCircuitBreaker);
            outJsonObject = this.sinkProcessor.process(inMessage.getData());
            return BizMessage.buildSuccessMessage(inMessage, outJsonObject);
        } catch (BizException e) {
            log.warn("Sink服务执行出错:{}-{}\n{}", e.getCode(),e.getMessage(),e.getExtMessage());
            return BizMessage.buildFailMessage(inMessage, e);
        }
        finally {
            BizTools.bizMessageThreadLocal.remove();
            SinkCircuitBreaker.sinkCircuitBreakerThreadLocal.remove();
        }
    }
}
